﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using Boo.Lang;
using Castle.Windsor;
using MbUnit.Framework;
using Mite.Configuration;
using Mite.DSL;
using Mite.MsSql;
using Moq;
using Rhino.DSL;

namespace Mite.Core.Tests.Unit
{
	[TestFixture]
	[Author("Nathan")]
	[Category("Unit")]
	public class MigrationBaseTestFixture
	{
		protected MiteEnvironment TestEnvironment
		{
			get { return _testEnvironment; }
		}

		[SetUp]
		public void Setup()
		{
			oldCurrentDirectory = Environment.CurrentDirectory;
			Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory + "\\";

			WindsorContainer windsor = new WindsorContainer();
			windsor.Register(
				Castle.MicroKernel.Registration.Component.For<IAdapterFactory>().ImplementedBy(typeof(AdapterFactory)));

			IoC.Init(windsor);
		}

		[TearDown]
		public void TearDown()
		{
			Environment.CurrentDirectory = oldCurrentDirectory;
		}

		[Test]
		public void Up_can_compile()
		{
			var factory = new DslFactory();
			factory.Register<MigrationBase>(new MigrationDslEngine());
			var migration = factory.Create<MigrationBase>(@"Unit\up_lowercase_001.boo", TestEnvironment);
			Assert.IsNotNull(migration);
		}

		[Test]
		public void CreateTable_can_compile()
		{
			MigrationBase migration = LoadMigration(@"Unit\create_table_001.boo");
			Assert.IsNotNull(migration);
		}

		[Test]
		public void DropTable_can_compile()
		{
			MigrationBase migration = LoadMigration(@"Unit\drop_table_001.boo");
			Assert.IsNotNull(migration);
		}

		[Test]
		public void Local_variables_can_compile()
		{
			MigrationBase migration = LoadMigration(@"Unit\local_variables_001.boo");
			Assert.IsNotNull(migration);
		}

		[Test]
		public void Local_variable_can_be_used_as_create_table_argument()
		{
			MigrationBase migration = LoadMigration(@"Unit\local_variables_add_table_argument_001.boo");
			Assert.IsNotNull(migration);
		}

		[Test]
		public void Local_variable_can_be_used_as_drop_table_argument()
		{
			MigrationBase migration = LoadMigration(@"Unit\local_variables_drop_table_argument_001.boo");
			Assert.IsNotNull(migration);
		}

		[Test]
		public void AddColumn_can_compile()
		{
			MigrationBase migration = LoadMigration(@"Unit\test_add_column_001.boo");
			Assert.IsNotNull(migration);
		}

		private MigrationBase LoadMigration(string url)
		{
			var factory = new DslFactory();
			factory.Register<MigrationBase>(new MigrationDslEngine());
			var migration = factory.Create<MigrationBase>(url, TestEnvironment);
			return migration;
		}

		private readonly MiteEnvironment _testEnvironment = new MiteEnvironment("bleh", typeof (MsSqlAdapter), "localhost",
		                                                                        "mite_test",
		                                                                        null, null, new Hash());

		private string oldCurrentDirectory;

		#region Nested type: MigrationStub

		private class MigrationStub : MigrationBase
		{
			public MigrationStub(MiteEnvironment environment) : base(environment)
			{
				var transactionMock = new Mock<IDbTransaction>(MockBehavior.Loose);
				Transaction = transactionMock.Object;
			}

			public override uint Version
			{
				get { return version; }
			}

			public IDbTransaction GetTransaction()
			{
				return Transaction;
			}

			protected override void Up()
			{
			}

            protected override void Down()
		    {
		    }


		    private uint version = 1;
		}

		#endregion
	}
}